package com.zy.yun.controller.sys;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageHelper;
import com.zy.yun.base.annotation.NotNullPara;
import com.zy.yun.base.common.DataTable;
import com.zy.yun.base.common.LTree;
import com.zy.yun.base.common.RestResult;
import com.zy.yun.base.constant.StatusEnum;
import com.zy.yun.base.constant.TypeEnum;
import com.zy.yun.base.entity.Res;
import com.zy.yun.base.entity.RoleRes;
import com.zy.yun.base.entity.User;
import com.zy.yun.base.entity.dto.ResDTO;
import com.zy.yun.base.entity.vo.ResVO;
import com.zy.yun.controller.common.BaseController;
import com.zy.yun.provider.service.IResService;
import com.zy.yun.provider.service.IRoleResService;
import com.zy.yun.utils.RedisUtil;
import com.zy.yun.utils.TableCacheUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 资源表 前端控制器
 * </p>
 *
 * @author 王彦委
 * @since 2019-09-19
 */
@RestController
@RequestMapping(value = "/res", name = "资源管理")
@Api(tags = "资源管理", description = "资源管理")
public class ResController extends BaseController<Res, ResVO> {

    @Autowired
    private TableCacheUtil tableCacheUtil;
    @Autowired
    private IResService resService;
    @Autowired
    private IRoleResService roleResService;
    @Autowired
    private RedisUtil<User,List> redisUtil;

    /**
     * 功能描述: 新增
     *
     * @auther: wangyanwei
     * @date: 2019/9/24 9:28
     * @param:
     * @return:
     */
    @PostMapping("save")
    @ApiOperation(value = "新增记录")
    public RestResult save(ResDTO resDTO) {

        if (StringUtils.isNotBlank(resDTO.getNote()) && resDTO.getNote().length() > 50) {
            return RestResult.buildError("备注最多50个字！");
        }
        resDTO.setCreateTime(new Date());
        resDTO.setStatus(StatusEnum.STATUS_START.getCode());
        if (resService.insert(resDTO)) {
            //更新 redis中 sys_res表缓存
            tableCacheUtil.updateTableSysRes();

            return RestResult.buildSuccess();
        }
        return RestResult.buildError();
    }


    /**
     * 功能描述: 获取菜单
     *
     * @param pid: 1级菜单的数据库pid
     * @auther: wangyanwei
     * @date: 2019/9/21 10:45
     * @return:
     */
    @ApiOperation("获取菜单")
    @PostMapping(value = "getMenu", name = "获取菜单")
    public RestResult getMenu(@RequestParam("nodeIds") List<Long> nodeIds, String pid, HttpServletRequest request) {

        //获取token
        String token = request.getHeader("Authorization");
        User user = redisUtil.getObject(token, User.class);
        //根据角色查询用户对应的菜单


        EntityWrapper<Res> queryWrapper = new EntityWrapper<Res>();


        List<Res> resList = null;
        if (null != pid ) {
            queryWrapper.eq("pid", pid);
            Res res = resService.selectOne(queryWrapper);
            queryWrapper.eq("type", TypeEnum.RES_MENU.getCode());
            queryWrapper.eq("status", StatusEnum.STATUS_START.getCode());
            EntityWrapper<Res> resQueryWrapper = new EntityWrapper<>();
            resQueryWrapper.eq("pid", res.getId());
            resList = resService.selectList(resQueryWrapper);
        }else {
            //菜单列表
            //查询 所有一级菜单
            queryWrapper.lt("pid", "0");
            resList = resService.selectList(queryWrapper);
        }


        List<LTree> lTrees = getLTrees(resList, nodeIds);

        return RestResult.buildSuccess(lTrees);
    }

    /**
     * 功能描述: 查询子菜单
     *
     * @auther: wangyanwei
     * @date: 2019/9/22 13:28
     * @param:
     * @return:
     */
    private List<LTree> getLTrees(List<Res> resList, List<Long> nodeIds) {
        List<LTree> lTrees = new ArrayList<>();

        for (Res res : resList) {
            LTree lTree = new LTree();
            lTree.setId(res.getId());
            lTree.setTitle(res.getName());
            lTree.setIconCls(res.getIconCls());
            lTree.setHref(res.getUrl());
            if (nodeIds.contains(res.getId())) {
                lTree.setSpread(true);
            }
            EntityWrapper<Res> queryWrapper = new EntityWrapper<Res>();
            queryWrapper.eq("type", TypeEnum.RES_MENU.getCode());
            queryWrapper.eq("pid", res.getId());
            queryWrapper.eq("status", StatusEnum.STATUS_START.getCode());
            List<Res> list = resService.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                lTrees.add(lTree);
                continue;
            }
            lTree.setChildren(getLTrees(list, nodeIds));
            lTrees.add(lTree);
        }
        return lTrees;
    }


    /**
     * @Author: 王彦委
     * @Description: 查询开以分配权限的资源
     * @Date: 21:27 2019/10/20
     */
    @ApiOperation("查询分配权限的资源")
    @PostMapping("getAuthResTree")
    @NotNullPara({"roleId"})
    public RestResult getAuthResTree(Long roleId) {

        //1：查询所有开启的资源
        EntityWrapper<Res> resQueryWrapper = new EntityWrapper<>();
        resQueryWrapper.eq("status", StatusEnum.STATUS_START.getCode());
        resQueryWrapper.lt("pid","0");
        List<Res> list = resService.selectList(resQueryWrapper);

        //2: 查询本角色拥有的资源
        EntityWrapper<RoleRes> roleResQueryWrapper = new EntityWrapper<>();
        roleResQueryWrapper.eq("roleId", roleId);
        List<RoleRes> roleResList = roleResService.selectList(roleResQueryWrapper);
        List<LTree> resLTrees = getResLTrees(list, roleResList);

        return RestResult.buildSuccess(resLTrees);
    }


    /**
     * @Author: 王彦委
     * @Description: 查询子资源
     * @Date: 21:35 2019/10/20
     */
    private List<LTree> getResLTrees(List<Res> resList, List<RoleRes> roleResList) {
        List<LTree> lTrees = new ArrayList<>();

        for (Res res : resList) {
            LTree lTree = new LTree();
            lTree.setId(res.getId());
            lTree.setTitle(res.getName());
            lTree.setIconCls(res.getIconCls());
            lTree.setHref(res.getUrl());
            lTree.setChecked(false);
            EntityWrapper<Res> queryWrapper = new EntityWrapper<Res>();
            queryWrapper.eq("pid", res.getId());
            queryWrapper.eq("status", StatusEnum.STATUS_START.getCode());
            List<Res> list = resService.selectList(queryWrapper);
            if (CollectionUtils.isEmpty(list)) {
                //只把最后一级设置成选中
                for (RoleRes roleRes : roleResList) {
                    if (res.getId().equals(roleRes.getResId())) {
                        System.err.println("resId=" + res.getId() + " roleResId=" + roleRes.getResId());
                        lTree.setChecked(true);
                    }
                }
                lTrees.add(lTree);
                continue;
            }
            lTree.setChildren(getResLTrees(list, roleResList));
            lTrees.add(lTree);
        }
        return lTrees;
    }


    /**
     * 功能描述: 查询菜单带分页，默认条件根据 pid查询
     *
     * @auther: wangyanwei
     * @date: 2019/9/20 14:20
     * @param:
     * @return:
     */
    @ApiOperation(value = "资源列表")
    @PostMapping(value = "findPage", name = "资源列表")
    public DataTable getResPage(ResDTO resDTO, @RequestParam(defaultValue = "30") Integer pageNum, @RequestParam(defaultValue = "0") Integer pageSize) {

        PageHelper.startPage(pageNum, pageSize, true);
        EntityWrapper<Res> resQueryWrapper = new EntityWrapper<>();
        resQueryWrapper.orderBy("seq");
        resQueryWrapper.orderBy("createTime");

        if (null == resDTO.getFlag()) {
            if (null == resDTO.getPid()) {
                //规定所有一级菜单pid,都小于 0
                resQueryWrapper.lt("pid","0");
            } else {
                resQueryWrapper.eq("pid", resDTO.getPid());
            }
        } else if (null != resDTO.getPid()) {
            resQueryWrapper.eq("pid", resDTO.getPid());
        }

        if (StringUtils.isNotBlank(resDTO.getName())) {
            resQueryWrapper.like("name", resDTO.getName());
        }
        if (StringUtils.isNotBlank(resDTO.getType())) {
            resQueryWrapper.eq("type", resDTO.getType());
        }
        if (StringUtils.isNotBlank(resDTO.getStatus())) {
            resQueryWrapper.eq("status", resDTO.getStatus());
        }

        return findPage(resQueryWrapper, pageNum, pageSize);
    }

    /**
     * 功能描述: 批量删除菜单 或 资源
     *
     * @param menuId: 菜单id
     * @param ids:    资源id
     * @auther: wangyanwei
     * @date: 2019/9/24 11:45
     * @return:
     */
    @ApiOperation(value = "根据id批量删除资源")
    @PostMapping("batchDeleteRes")
    @ApiImplicitParam(value = "ids", defaultValue = "资源id")
    public RestResult batchDeleteRes(Long menuId, @RequestParam("ids") List<Long> ids) {

        //1:处理资源
        if (CollectionUtils.isNotEmpty(ids)) {
            if (resService.deleteBatchIds(ids)) {
                return RestResult.buildSuccess();
            }
            return RestResult.buildError();

        }
        //2：处理菜单
        if (null == menuId) {
            return RestResult.buildError("至少选择一项!");
        }

        //查询其下还有没有子节点
        EntityWrapper<Res> menuQuery = new EntityWrapper<>();
        menuQuery.eq("pid", menuId);
        if (CollectionUtils.isNotEmpty(resService.selectList(menuQuery))) {
            return RestResult.buildError("请先删除本菜单下的资源！");
        }
        if (resService.deleteById(menuId)) {
            //更新 redis中 sys_res表缓存
            tableCacheUtil.updateTableSysRes();
            return RestResult.buildSuccess();
        }
        return RestResult.buildError();
    }

    /**
     * 功能描述: 根据id,修改
     *
     * @auther: wangyanwei
     * @date: 2019/9/27 14:24
     * @param:
     * @return:
     */
    @ApiOperation(value = "根据id修改")
    @PostMapping("updateRes")
    @NotNullPara({"id"})
    public RestResult updateRes(ResDTO resDTO) {
        if (resService.updateById(resDTO)) {
            //更新 redis中 sys_res表缓存
            tableCacheUtil.updateTableSysRes();
            return RestResult.buildSuccess();
        }
        return RestResult.buildError();

    }

    /**
     * 功能描述: 批量修改 ，开启、暂停资源
     *
     * @auther: wangyanwei
     * @date: 2019/9/27 8:56
     * @param:
     * @return:
     */
    @ApiOperation(value = "批量修改资源状态")
    @PostMapping("batchUpdateRes")
    @ApiImplicitParam(value = "ids", defaultValue = "资源id")
    @NotNullPara({"status"})
    public RestResult batchUpdateRes(String status, @RequestParam("ids") List<Long> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            return RestResult.buildError("请先选择！");
        }
        if (StatusEnum.STATUS_START.getCode().equalsIgnoreCase(status) && StatusEnum.STATUS_STOP.getCode().equalsIgnoreCase(status)) {
            return RestResult.buildError("状态错误！");
        }
        ArrayList<Res> resList = new ArrayList<>();
        for (Long id : ids) {
            Res res = new Res();
            res.setId(id);
            res.setStatus(status);
            resList.add(res);
        }
        if (resService.updateBatchById(resList)) {
            //更新 redis中 sys_res表缓存
            tableCacheUtil.updateTableSysRes();
            return RestResult.buildSuccess();
        }
        return RestResult.buildError();
    }

}
